package com.ruoyi.web.api;

import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.aspectj.DataScopeAspect;
import com.ruoyi.system.service.ISysDeptService;
import lombok.extern.slf4j.Slf4j;
import org.openapi.common.ApiException;
import org.openapi.consts.ApiConst;
import org.openapi.consts.EventType;
import org.openapi.service.IDbService;
import org.openapi.utils.StrUtil;
import org.openapi.vo.TableData;
import org.openapi.vo.TableQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.openapi.common.ApiUser;
import org.openapi.service.IOpenApiService;

import java.io.File;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

/**
 * API自定义业务实现
 */
@Service
@Slf4j
public class OpenApiServiceImpl implements IOpenApiService {

    @Autowired
    private ISysDeptService sysDeptService;
    @Autowired
    private IDbService dbService;

    @Override
    public ApiUser getLoginUser() {
        ApiUser user = new ApiUser();
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        user.setUserId(sysUser.getUserId()+"");
        user.setAccount(sysUser.getUserName());
        user.setUsername(sysUser.getNickName());
        user.setOrgId(sysUser.getDeptId()+"");
        user.setOrgName(sysUser.getDept().getDeptName());
        user.setRoles(sysUser.getRoles().stream().map(r->r.getRoleId().toString()).toArray(String[]::new));

        if(SecurityUtils.isAdmin(sysUser.getUserId())){
            user.setDataScope(ApiUser.DATA_SCOPE_ALL);
        }else{
            //数值从小到大，对应的数据范围从大到小
            SysRole dsRole = sysUser.getRoles().stream().sorted(Comparator.comparing(SysRole::getDataScope)).findFirst().get();

            if(DataScopeAspect.DATA_SCOPE_ALL.equalsIgnoreCase(dsRole.getDataScope())){
                //若依全部权限
                user.setDataScope(ApiUser.DATA_SCOPE_ALL);
            }else if(DataScopeAspect.DATA_SCOPE_SELF.equalsIgnoreCase(dsRole.getDataScope())){
                //若依用户权限
                user.setDataScope(ApiUser.DATA_SCOPE_USER);
            }else if(DataScopeAspect.DATA_SCOPE_DEPT.equalsIgnoreCase(dsRole.getDataScope())){
                //若依本部门权限
                user.setDataScope(ApiUser.DATA_SCOPE_ORG);
                String[] ids = {user.getOrgId()};
                user.setOrgIds(ids);
            }else if(DataScopeAspect.DATA_SCOPE_DEPT_AND_CHILD.equalsIgnoreCase(dsRole.getDataScope())){
                //若依本部门及下级部门权限
                user.setDataScope(ApiUser.DATA_SCOPE_ORG);

                SysDept sysDept = sysDeptService.selectDeptById(sysUser.getDeptId());
                String deptIds = (sysDept == null ? user.getOrgId() : sysDept.getAncestors()+","+user.getOrgId());
                user.setOrgIds(deptIds.split(","));
            }else if(DataScopeAspect.DATA_SCOPE_CUSTOM.equalsIgnoreCase(dsRole.getDataScope())){
                //若依自定义权限
                user.setDataScope(ApiUser.DATA_SCOPE_ORG);
                user.setOrgIds(StrUtil.join(dsRole.getDeptIds(),",").split(","));
            }else{
                //若依未知权限
                user.setDataScope(ApiUser.DATA_SCOPE_USER);
            }
        }
        return user;
    }

    @Override
    public Boolean isAdmin() {
        return SecurityUtils.getUserId().equals(1L);
    }

    /**
     * 文件上传目录
     * @param excelFolder 业务目录
     * @return
     */
    @Override
    public String getUploadPath(String excelFolder){
        String path = RuoYiConfig.getProfile();
        if(path.endsWith("/") || path.endsWith("\\")){
            // skip
        }else{
            path+= "/";
        }
        if(excelFolder != null){
            path += excelFolder+"/";
        }
        File folder = new File(path);
        if(!folder.exists()){
            folder.mkdirs();
        }
        return path;
    }

    /**
     * 删除长时间未下载的excel文件,做定时任务调用
     * @param excelFolder 业务目录
     */
    @Override
    public void cleanExcel(String excelFolder){
        String path = getUploadPath(excelFolder);
        File folder = new File(path);
        if(!folder.exists()){
            return;
        }
        File[] fs = folder.listFiles();
        if(fs == null || fs.length == 0){
            return;
        }

        Long ct = System.currentTimeMillis();
        for(File f:fs){
            //删除一个小时之前的文件
            if(f.lastModified() + 1000 * 60 * 10 < ct){
                f.delete();
            }
        }
    }

    /**
     * 响应模型事件，建议非阻塞实现
     * @param modelCode 模型
     * @param event 事件
     * @param data 参数
     */
    @Override
    public void callEvent(String modelCode, String event, Object data){
        //事件响应
        log.debug("app event process {}-{}, params \r\n {}", modelCode, event, data);
        if(modelCode.equalsIgnoreCase("flow_task") && event.equalsIgnoreCase(EventType.AU.getCode())){
            //审批之后同步更新关联的业务状态
            Map updateData = (Map) data;
            if(!updateData.containsKey("check_status") || ApiConst.STATUS_ENABLED.equalsIgnoreCase(updateData.get("check_status").toString())){
                return;
            }

            //审批通过或不通过之后，更新业务状态
            TableQuery query = new TableQuery();
            query.setTable("flow_task");
            query.addData("id", ((Map)data).get("id"));
            Map task = dbService.find(query);
            if(task == null || task.isEmpty()){
                return;
            }

            TableData table = new TableData();
            table.setTable(task.get("type").toString());
            table.addData("id", task.get("target_id"));
            table.addData("check_status", updateData.get("check_status"));
            table.setIgnore(true);
            dbService.updateData(table);
        }else if(modelCode.equalsIgnoreCase("asset_purchase") && event.equalsIgnoreCase(EventType.BU.getCode())){
            //采购完成前，要确认明细都入库完成
            Map updateData = (Map) data;
            if(!updateData.containsKey("apply_status") || !"4".equalsIgnoreCase(updateData.get("apply_status").toString())){
                return;
            }

            //审批通过或不通过之后，更新业务状态
            List<Map<String,Object>> list = dbService.query("SELECT count(id) total FROM asset_purchase_detail WHERE amount!= ins AND purchase_id="+((Map)data).get("id"));
            if(list == null || list.isEmpty() || Integer.parseInt(list.get(0).get("total").toString()) == 0){
                return;
            }else{
                throw new ApiException("还有设备未采购完成");
            }
        }
    }
}
